/*
 * Copyright (C) 2010 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.emmp_ard.scan.decoding;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.emmp_ard.carplate.CarPlateDetection;
import com.emmp_ard.carplate.IntCharPair;
import com.emmp_ard.scan.camera.CameraManager;
import com.emmp_ard.scan.camera.PlanarYUVLuminanceSource;
import com.emmp_ard.scancapture.ScanCaptureActivity;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.huaxin.common.Entity.BaseDTO;
import com.huaxin.common.cache.DiskCache;
import com.huaxin.common.tools.RequestHelper;
import com.huaxin.hxcloud.R;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Response;


public final class DecodeHandler extends Handler {

    private static final String TAG = DecodeHandler.class.getSimpleName();
    private static final String TEMP_IMG = "temp.jpg";

    private final ScanCaptureActivity activity;
    private final MultiFormatReader multiFormatReader;
    private static String mDataRootPath;

    public static boolean TEST = false;
    public static ArrayList<String> results = new ArrayList<String>();
    public static ArrayList<IntCharPair> cps = new ArrayList<IntCharPair>();
    public final static int PRO_TIME = 10;
    public final static int CAL_TIME = 5;
    public static int counter = -1;
    public final static int RES_LENGTH = 10;
    public static int c_weight[][] = new int[PRO_TIME + 2][RES_LENGTH]; //c_weight[PRO_TIME][]作为比较权值的哨兵记录最大值
    //c_weight[PRO_TIME+1][]记录权值最大的位置
    public static int s_weight[] = new int[PRO_TIME + 2];
    //    private static final int[] indexs = new int[]{1, 2, 4, 5, 6, 7, 8};
    public static int errors = 0;


    DecodeHandler(ScanCaptureActivity activity,
                  Hashtable<DecodeHintType, Object> hints) {
        multiFormatReader = new MultiFormatReader();
        multiFormatReader.setHints(hints);
        this.activity = activity;
    }

    @Override
    public void handleMessage(Message message) {
        if (message.what == R.id.decode) {
            // Log.d(TAG, "Got decode message");
            removeMessages(R.id.clear);
            sendEmptyMessageDelayed(R.id.clear, 3000);
            decode((byte[]) message.obj, message.arg1, message.arg2);
        } else if (message.what == R.id.quit) {
            removeMessages(R.id.clear);
            Looper.myLooper().quit();
        } else if (message.what == R.id.clear) {
            removeMessages(R.id.clear);
            counter = -1;
        }
    }

    /**
     * Decode the data within the viewfinder rectangle, and time how long it
     * took. For efficiency, reuse the same reader objects from one decode to
     * the next.
     *
     * @param data   The YUV preview frame.
     * @param width  The width of the preview frame.
     * @param height The height of the preview frame.
     */
    private void decode(byte[] data, int width, int height) {
        if  (data!=null){
            long start = System.currentTimeMillis();
            if (CarPlateDetection.TEST) {
                String ret = null;
                File file= saveBitmap(data, width, height);
                RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                MultipartBody.Part part = MultipartBody.Part.createFormData("file",file.getName(), requestBody);
                Call<BaseDTO> call = RequestHelper.getRequestApi().sweep1(part);
                try {
                    Response<BaseDTO> response = call.execute();
                    BaseDTO baseDTO = response.body();
                    if(baseDTO!=null&&baseDTO.isSuccessful()){
                        //                   ret = ProByhx(baseDTO.getMsg());
                        ret = baseDTO.getMsg();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.d("Zoes","4");
                if (ret != null) {
                    long end = System.currentTimeMillis();
                    Log.d(TAG, "Found car (" + (end - start) + " ms):\n" + ret);
                    Message message = Message.obtain(activity.getHandler(),
                            R.id.decode_succeeded, ret);
                    message.sendToTarget();
                } else {
                    Message message = Message.obtain(activity.getHandler(),
                            R.id.decode_failed);
                    message.sendToTarget();
                }

            } else {
                Result rawResult = null;

                byte[] rotatedData = new byte[data.length];
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++)
                        rotatedData[x * height + height - y - 1] = data[x + y
                                * width];
                }
                int tmp = width; // Here we are swapping, that's the difference to
                // #11
                width = height;
                height = tmp;
                //
                // data = rotatedData;
                //
                PlanarYUVLuminanceSource source = CameraManager.get()
                        .buildLuminanceSource(rotatedData, width, height);

                // final byte[] get_extra = source.getMatrix();

                BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

                try {
                    rawResult = multiFormatReader.decodeWithState(bitmap);
                } catch (ReaderException re) {
                    // continue
                } finally {
                    multiFormatReader.reset();
                }
                if (rawResult != null) {
                    long end = System.currentTimeMillis();
                    Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n"
                            + rawResult.toString());
                    Message message = Message.obtain(activity.getHandler(),
                            R.id.decode_succeeded, rawResult);
                    Bundle bundle = new Bundle();
                    bundle.putParcelable(DecodeThread.BARCODE_BITMAP,
                            source.renderCroppedGreyscaleBitmap());
                    message.setData(bundle);
                    // Log.d(TAG, "Sending decode succeeded message...");
                    message.sendToTarget();
                } else {
                    Message message = Message.obtain(activity.getHandler(),
                            R.id.decode_failed);
                    message.sendToTarget();
                }
            }
        }

    }



    public static File saveBitmap(byte[] data_, int width, int height) {
        final YuvImage yuv = new YuvImage(data_, ImageFormat.NV21, width,
                height, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);

        byte[] bytes = out.toByteArray();
        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        // // 创建新的图片
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);

        Rect rect = CameraManager.get().getFramingRectInPreview();
        matrix.postRotate(0);
        matrix.setScale(0.5f, 0.5f);
        bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height(), matrix, true);
        if( !DiskCache.putBitmap(TEMP_IMG,bitmap)){
            return null;
        }
        return DiskCache.getFile(TEMP_IMG);
    }


    private static String ProByhx(String result) {
        // TODO Auto-generated method stub
        Log.d("Zoes", "result: " + result);
        result = result.replaceAll("\\s*|\t|\r|\n", "");
        if(result.length()!=RES_LENGTH){
            return null;
        }
        if (counter == -1) {
            for (int i = 0; i < PRO_TIME + 2; i++) {
                for (int j = 0; j < RES_LENGTH; j++)
                    c_weight[i][j] = 0;
            }
        }
        results.add(result);
        counter++;
        for (int i = 0; i < counter; i++) {
            String temp = results.get(i);
            for (int j = 0; j < cps.size(); j++) {
                IntCharPair temPair = cps.get(j);
                if (temPair != null && temPair.m_char == temp.charAt(temPair.m_int)) {
                    c_weight[counter][temPair.m_int] = c_weight[counter][temPair.m_int] + 2;

                }
            }
            //Log.d("Zoes", "rlen" + result.length() + ".te" + temp.length());
            if (result.length() == RES_LENGTH && temp.length() == RES_LENGTH) {
                for (int j = 0; j < RES_LENGTH; j++) {    //否则计算相同字符的个数
                    if (result.charAt(j) == temp.charAt(j)) {
                        c_weight[i][j]++;
                        c_weight[counter][j]++;
                    }
                }
            }
        }


        if (counter < CAL_TIME - 1) {
            return null;
        }

        for (int i = 0; i < CAL_TIME; i++) {    //查找每一位权值最高的字符
            for (int j = 0; j < RES_LENGTH; j++)
                if (c_weight[i][j] > c_weight[PRO_TIME][j]) {
                    c_weight[PRO_TIME][j] = c_weight[i][j];  //字符保存在c_weight[PRO_TIME][j]
                    c_weight[PRO_TIME + 1][j] = i;           //权值最高的字符所在字符串的位置保存在c_weight[PRO_TIME + 1][j]
                }
        }


        boolean flag = false;
        boolean ChiniseFlag = true;
        cps.clear();
        for (int i = 0; i < RES_LENGTH; i++) {            //权值低于2，将重新取样
            if (c_weight[PRO_TIME][i] < 2) {
                if (i == 3) {
                    ChiniseFlag = false;
                    continue;
                }
                flag = true;

            } else {
                cps.add(new IntCharPair(i, results.get(c_weight[PRO_TIME + 1][i]).charAt(i)));
            }
        }
        if (flag) {
            counter = -1;
            results.clear();
            return null;
        }
        char c_result[] = new char[RES_LENGTH];

        for (int i = 0; i < RES_LENGTH; i++) {
            if (i == 3 && ChiniseFlag == false) {
                c_result[i] = '\0';
                continue;
            }
            c_result[i] = results.get(c_weight[PRO_TIME + 1][i]).charAt(i);
        }

        counter = -1;
        results.clear();

        String ret = String.valueOf(c_result);

        return ret;
    }

    public static int[] getRow(int[] yuvData, int dataWidth, int y, Rect rect) {
        int[] row = new int[rect.width()];
        int offset = (y + rect.top) * dataWidth + rect.left;
        System.arraycopy(yuvData, offset, row, 0, rect.width());
        return row;
    }



}
